<?php

namespace app\controller;

use lib\View;
use lib\Tools;

abstract class Core
{
    protected $controller;
    protected $action;
    protected $method;
    protected $config;
    protected $url;
    protected $auth;
    protected $pageParam = [];
    protected $postData;
    protected $_view;

    /**
     * 初始化
     *
     */
    public function __construct($params=[])
    {
        $this->controller = empty($params[0])?'Index':$params[0];
        $this->action     = empty($params[1])?'index':$params[1];
        $this->method     = $_SERVER['REQUEST_METHOD'];
        $this->url        = $_SERVER['REQUEST_URI'];
        $params= array_splice($params, 2, count($params), true);
        for ($i=0; $i<sizeof($params); $i+=2){
            $this->pageParam[$params[$i]] = $params[$i+1];
        }
        $this->config     = getConfig();
        $this->postData   = $this->getPost();
        $this->pageParam  = array_merge($this->pageParam, $this->getQuery(), $this->getPost());
        $this->_initView();
    }



    public function _initView()
    {
        $this->_view = new View();
    }

    /**
     * get one parameter
     * @param string $name
     * @param string $default
     * @return array|string|unknown_type
     * ex: $this->get('imgs/a');    //array
     * ex: $this->get('age/d');     //integer
     * ex: $this->get('height/f');  //float
     * ex: $this->get('gender/b');  //bool
     * ex: $this->get('name/s');    //sting
     */
    protected function get($name = '', $default = '')
    {
        if (empty($name)) {
            return $this->pageParam;
        } else {
            if (strpos($name, '?') === false) {
                if (strpos($name, '/')) {
                    [$name, $type] = explode('/', $name);
                }
                $value = $this->pageParam[$name] ?? $default;
                $value = Tools::filter($value);
                if (is_null($value)) {
                    return $default;
                }
                if (is_object($value)) {
                    return $value;
                }
                if (isset($type) && $value !== $default) {
                    // 强制类型转换
                    $this->typeCast($value, $type);
                }
                return $value;
            } else {
                return isset($this->pageParam[str_replace('?', '', $name)]);
            }
        }
    }

    /**
     * 强制类型转换
     * @access public
     * @param string $data
     * @param string $type
     * @return mixed
     */
    private function typeCast(&$data, $type)
    {
        switch (strtolower($type)) {
            // 数组
            case 'a':
                $data = (array)$data;
                break;
            // 数字
            case 'd':
                $data = (int)$data;
                break;
            // 浮点
            case 'f':
                $data = (float)$data;
                break;
            // 布尔
            case 'b':
                $data = (boolean)$data;
                break;
            // 字符串
            case 's':
                if (is_scalar($data)) {
                    $data = (string)$data;
                } else {
                    throw new \InvalidArgumentException('variable type error：' . gettype($data));
                }
                break;
        }
    }

    /**
     * @param string $name
     * @param string $default
     * @return array|string|unknown_type
     */
    protected function input($name = '', $default = '')
    {
        return $this->get($name, $default);
    }

    /**
     * Get
     * @param string $name
     * @param string $default
     * @return array|unknown_type
     */
    protected function getQuery($name = '', $default = '')
    {
        if (empty($name)) {
            return $_GET;
        } else {
            $value = $_GET[$name]??$default;
            $value = Tools::filter($value);
            return $value;
        }
    }

    /**
     * Post
     * @param string $name
     * @param string $default
     * @return array|mixed|unknown_type
     */
    protected function getPost($name = '', $default = '')
    {
        $json = $this->parse_json(file_get_contents("php://input"));
        if (empty($json)) {
            if (empty($name)) {
                return $_POST;
            } else {
                $value = $_POST[$name]??$default;
                $value = Tools::filter($value);
                return $value;
            }
        } else {
            if (empty($name)) {
                return $json;
            } else {
                $value = $json[$name];
                $value = Tools::filter($value);
                return $value;
            }
        }
    }

    protected function parse_json($string)
    {
        $json = json_decode($string, TRUE);
        if (json_last_error() == JSON_ERROR_NONE) {
            return $json;
        } else {
            return [];
        }
    }

    /**
     * request
     * @param string $name
     * @param string $default
     * @return array|unknown_type
     */
    protected function getCookie($name = '', $default = '')
    {
        $value = $_COOKIE[$name] ?? $default;
        $value = Tools::filter($value);
        return $value;
    }

    protected function isXml()
    {
        return $this->getRequest()->isXmlHttpRequest();
    }

    protected function isPost()
    {
        return $this->getRequest()->isPost();
    }

    protected function isPut()
    {
        return $this->getRequest()->isPut();
    }

    protected function isGet()
    {
        return $this->getRequest()->isGet();
    }

    /**
     *记录SQL日志
     *前置 DB::enableQueryLog();
     */
    protected function sqlLog()
    {
        $sqllogs = DB::getQueryLog();
        foreach ($sqllogs as $onesql) {
            $query    = str_replace('?', '%s', $onesql['query']);
            $bindings = $onesql['bindings'];
            array_walk($bindings, function (&$v) {
                $v = "'$v'";
            });

            array_unshift($bindings, $query);
            $sql = call_user_func_array('sprintf', $bindings);
            \Log::out('sql', 'I', call_user_func_array('sprintf', $bindings));
        }
    }

}
